package com.example.demo.service;

import com.example.demo.utils.BigDecimalUtils;
import com.example.demo.utils.JsonUtil;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author linjingze
 * @date 2023/12/19 10:58 AM
 */
public class DeliveryPriceService {


    public BigDecimal getDeliveryPrice(String area, String warehouse, Integer useBoard) {
        String config = DeliveryPriceConfig.getConfig(area);
        if (StringUtils.isBlank(config)) {
            throw new RuntimeException("未配置" + area + "的价格");
        }
        AreaWarehouseSell areaWarehouseSell = JsonUtil.deserialize(config, AreaWarehouseSell.class);
        WarehouseArea warehouseArea = areaWarehouseSell.getWarehouseAreaList().stream()
                .filter(s -> StringUtils.equals(s.getWarehouse(), warehouse)).findFirst()
                .orElse(null);
        if (warehouseArea == null) {
            return null;
        }
        return getBoardAmount(useBoard, warehouseArea, areaWarehouseSell.getBoardOfCar());
    }


    private static BigDecimal getBoardAmount(Integer useBoard, WarehouseArea warehouseArea, Integer boardOfCar) {
        if (useBoard == 0) {
            return BigDecimal.ZERO;
        }
        List<AreaPrice> areaPriceList = warehouseArea.getAreaPriceList().stream().sorted().toList();
        BigDecimal fullPrice = warehouseArea.getFullPrice();
        if (fullPrice == null) {
            fullPrice = new BigDecimal(Integer.MAX_VALUE);
        }
        for (AreaPrice areaPrice : areaPriceList) {
            Integer min = areaPrice.getMin();
            Integer max = areaPrice.getMax();
            if (useBoard >= min && useBoard <= max) {
                BigDecimal needMoney = BigDecimalUtils.mul(new BigDecimal(useBoard), areaPrice.getAmount());
                if (BigDecimalUtils.greaterThanOrEqual(needMoney, fullPrice)) {
                    return BigDecimalUtils.mul(BigDecimalUtils.divKeep6Scale(fullPrice, new BigDecimal(boardOfCar)), new BigDecimal(useBoard));
                }
                return needMoney;
            }
        }
        if (useBoard > boardOfCar) {
            int boardCount = useBoard / boardOfCar;
            Integer useSingleBoard = useBoard % boardOfCar;
            BigDecimal amount = BigDecimalUtils.mul(new BigDecimal(boardCount), fullPrice);
            return BigDecimalUtils.add(amount, getBoardAmount(useSingleBoard, warehouseArea, boardOfCar));
        } else {
            return BigDecimalUtils.mul(BigDecimalUtils.divKeep6Scale(fullPrice, new BigDecimal(boardOfCar)), new BigDecimal(useBoard));
        }
    }


}
